#include "widget.h"
#include "ui_widget.h"
#include <QChar>
#include <QString>
#include <QCoreApplication>
#include <string.h>
#include <stdlib.h>

//***********************************************************************************************

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);

    pixmap = new QPixmap();    //在堆中申请一段空间，QPixmap,对象为pixmap
    this->socket = new QTcpSocket(this); //创建套接字

    flag = 0;

    this->socket->connectToHost("192.168.1.56",10086); //设置通信ip和端口号
     timer = new QTimer(this); //申请一个定时器
    connect(timer,SIGNAL(timeout()),this,SLOT(recv_show())); //updatapic()该函数用来获取视频画面
    connect(socket,SIGNAL(connected()),this,SLOT(connectedSlot()));
    connect(socket,SIGNAL(disconnected()),this,SLOT(disconnectSlot()));
    connect(socket,SIGNAL(readyRead()),this,SLOT(recvDataSlot()));//读数据操作
    //ui->stackedWidget->setCurrentWidget(ui->loginPage);

    //视频界面按钮开始状态
    ui->pushButton_c1->setEnabled(true);//开启视频按钮的初值给true，一开始给使能
    ui->pushButton_c2->setEnabled(false);//关闭视频按钮的初值给false，一开始不使能
    //ui->pushButton_4->setFlat(true); //模式按钮隐藏

    ui->label_11->hide();

}

//***********************************************************************************************

Widget::~Widget()
{
    delete ui;
}

//***********************************************************************************************

void Widget::recvDataSlot()
{
    //接受消息
    data = socket->readAll();

    //将QByteArr转换为MSG结构体
    memcpy(&msg, data.data(), DATASIZE);

    qDebug()<<"Data is coming..."<<"###"<<QString(data.data());
    qDebug()<<"op is coming..."<<"###"<<msg.op;
    qDebug()<<"Data is "<<"###"<<QString(msg.data);

//---------------------------------------
    //被动接收信号的情况
    if (msg.op == SMOG) //烟雾报警
    {
        str = msg.data;
        ui->tishi_2->setText(str);
    }
    else if (msg.op == INF_RAY) //人体传感器
    {
        //先判断一下是否可以显示图片
        str = msg.data;
        ui->tishi_2->setText(str);
        if (ui->tishi_2->text() == "有人闯入！")
        {
            ui->label_11->show(); //显示图片
            on_screenShot_clicked();
            return;
        }
    }

//---------------------------------------

    //判断操作
    switch (flag)
    {
//---------------------------------------
        //登陆
        case LOGIN:
            //判断返回值
            if(msg.op == -1)
            {
                ui->label->setText("登录失败，密码错误，请重新输入。");
                clearData();
            }
            else
            {
                //跳转页面
                ui->stackedWidget->setCurrentIndex(1);
            }
            break;
//---------------------------------------
        //摄像头
        case CAMERA:
            if(0 != strcmp(msg.data,"摄像头忙"))
            {
                moude = 0;
                qDebug() << "kaiqi camera";
                str = "摄像头空闲";
                ui->tishi_2->setText(str);

            }
            else
            { 
                 moude = 1;
                 str = msg.data;
                 ui->tishi_2->setText(str);
            }
            break;
//---------------------------------------
        //温度
        case TEMP:
            str = msg.data;
            //tev = str.toInt(); //转整形
            ui->tishi->setText(str);
            break;
//---------------------------------------
        //灯
        case LIGHT:
            str = msg.data;
            ui->tishi_2->setText(str);
           break;
//---------------------------------------
         //空调
         case AIRCON:
            str = msg.data;
            ui->tishi_2->setText(str);
           break;
//---------------------------------------
        //模式选择
    case MOD:
        str = msg.data;
        ui->tishi_2->setText(str);
        break;
        default:
            QMessageBox::information(this,"信息","没有找到相应的选项",QMessageBox::Yes);
            break;
    }
}

//***********************************************************************************************

//发送
void Widget::sendData()
{
    //将结构体转换为QByteArray类型
    data.resize(sizeof(MSG));
    msg.userOrDevice = USER;
    memcpy(data.data(),&msg,sizeof(MSG));

    socket->write(data);
    //清空数据
    clearData();
}

//***********************************************************************************************

//清空数据
void Widget::clearData()
{
    memset(data.data(),0,sizeof(MSG));
    memset(&msg,0,sizeof(MSG));
}

//***********************************************************************************************

//点击登录
void Widget::on_login_clicked()
{
    flag = LOGIN;
    strcpy(msg.data,ui->input_passwd->text().toLatin1()); //获取用户输入密码
    msg.op = flag; //将选项标记为登录
    //发送密码
    sendData();
}

//***********************************************************************************************

//点击打开空调
void Widget::on_air_con_clicked()
{
    if (ui->air_con->text() == "打开空调")
    {
        flag = AIRCON;
        msg.op = flag;
        strcpy(msg.data,"open");
        //发送打开指令
        sendData();
        ui->air_con->setText("关闭空调");
        ui->label_10->setText("open");
    }
    else if (ui->air_con->text() == "关闭空调")
    {
        flag = AIRCON;
        msg.op = flag;
        strcpy(msg.data,"close");
        //发送关闭指令
        sendData();
        ui->air_con->setText("auto");
        ui->label_10->setText("close");
    }
    else
    {
        flag = AIRCON;
        msg.op = flag;
        strcpy(msg.data, "auto");
        //发送auto指令
        sendData();
        ui->air_con->setText("打开空调");
        ui->label_10->setText("auto");
    }
}

//***********************************************************************************************
//摄像头功能
//功能界面按钮，进入摄像头界面
void Widget::on_Camera_clicked()
{
    flag = CAMERA;
    msg.op = flag;
    sendData();
    Widget::sleep(500);
    if(0 == moude)
    {
        if(NULL != this->socket2)
        {
            this->socket2->close();
            this->socket2 = NULL;
            if(timer->isActive())
                timer->stop();
        }
        openVideo();
        ui->stackedWidget->setCurrentIndex(4); //跳转摄像头页面
    }      
}

//打开画面
void Widget::on_pushButton_c1_clicked()
{
    if(NULL == this->socket2)
    {
		openVideo();
    }
    ui->pushButton_c1->setEnabled(false);//开启视频后让此按钮变灰
    ui->pushButton_c2->setEnabled(true);//已经开启视频后让关闭视频按钮变黑（true）
    if(timer->isActive())
        timer->stop();
    timer->start(100);
}

//打开摄像头
void Widget::openVideo(void)
{
    Widget::sleep(3000);
    if(NULL == this->socket2)
    {

        //先进性判断是否开启了无人模式，是的话只执行打开画面，否则要执行这些。1
        this->socket2 = new QTcpSocket();
        this->socket2->connectToHost("192.168.1.56",8888);    //连接对应的IP和端口号
        //发送信号者为socket这个实例，发送的信号是connected(),接收者为Form,槽函数为msconnected()
        connect(this->socket2, SIGNAL(connected()), this, SLOT(msconnected()));
        connect(this->socket2, SIGNAL(disconnected()), this, SLOT(msdisconnected()));

    }
}

//摄像头连接上的话
void Widget::msconnected()
{
    qDebug() << "connected";
    if(timer->isActive())
        timer->stop();
    timer->start(100);
}

//摄像头连接不上的话
void Widget::msdisconnected()
{
    if(timer->isActive())
        timer->stop();
    ui->pushButton_c1->setEnabled(true);//按下关闭视频按钮后让开启视频按钮变黑（true）
    ui->pushButton_c2->setEnabled(false);//按下关闭视频按钮后让关闭按钮变灰（false）
    this->socket2->close();  //若连接失败，则关闭套接字，断开连接
    this->socket2 = NULL;
}

//摄像头连接上的话，就可获取画面
void Widget::recv_show()
    {
    int ret;
    char *request = "pic";      //请求命令
    char response[20];          //服务器发给QT的回复
    char *len;                  //
    unsigned int piclen;        //图片长度
    char picbuf[1024 * 1024];   //存放图片



    ret = this->socket2->write(request, strlen(request));  //发送请求图片命令"pic",返回这个命令的长度
    if (ret != strlen(request)) {
      qDebug() << "send request failed";   //如果这个命令不是"pic",则关闭套接字
       timer->stop();
       this->socket2->close();
   }

    this->socket2->flush();    //刷新socket
    this->socket2->waitForReadyRead(30000);  //李潇：等待读数据，最多等待30秒

    memset(response, 0, sizeof(response));      //清空数组，该数组用来存服务器发来的回复
    ret = this->socket2->read(response, sizeof(response));   //读服务器发给QT的回复，返回值为回复内容的长度
    if (ret != sizeof(response)) {
        qDebug() << "recv response failed";     //若该返回值不等于服务器回复QT内容的长度，则说明接收失败，计数器停止，并关闭套接字
        timer->stop();
        this->socket2->close();
        this->socket2 = NULL;
    }

    len = strstr(response, "len");  //在数组（服务器给QT回复的内容）中，查找len,若有"len",则返回"len"的首地址
    if (len == NULL) {
        qDebug() << "response header is error";         //若内容中没有“len”,则回复失败，服务器未返回内容，则计数器停止，关闭套接字
        timer->stop();
       // this->socket2->close();
        this->socket2 = NULL;
    }

    *len = '\0';
    //从response中读取图片长度
    piclen = atoi(response); //将数组中读到的内容字符串转整型

    qDebug() << "piclen: " << piclen;   //测试，读

    int total = 0;
    //循环读取pic信息
    while (total < piclen) {
        ret = this->socket2->read(picbuf+total, piclen-total);   //将读到的内容（图片）放到picbuf中
        if (ret < 0) {
            qDebug() << "recv pic failed" << ret;   //若读到的长度<0,则接收“pic”失败，则计时器停止，关闭套接字
            timer->stop();
            this->socket2->close();
            this->socket2 = NULL;
            return;
        } else if (ret == 0) {
            this->socket2->waitForReadyRead(30000);  //若读到长度=0,则继续等待30秒
            continue;
            //break;
        } else
            total += ret;

        qDebug() << "total: " << total;
    }

    pixmap->loadFromData((const uchar *)picbuf, piclen, "JPEG");    //加载数据到picbuf,格式“jpeg”
    {
        ui->label_7->setPixmap(*pixmap);  //画面呈现到label
    }
}

//暂停摄像头
void Widget::on_pushButton_c2_clicked()
{
    qDebug() << "total:----11--------------- ";
    if(timer->isActive())
        timer->stop();  //当关闭摄像头键被按下，若计数器存在，则关闭计数器
   qDebug() << "total:------------------- ";    //测试
    ui->pushButton_c1->setEnabled(true);//按下关闭视频按钮后让开启视频按钮变黑（true）
    ui->pushButton_c2->setEnabled(false);//按下关闭视频按钮后让关闭按钮变灰（false）
}

//返回上级菜单
void Widget::on_pushButton_3_clicked()
{
    //this->socket2 = new QTcpSocket();
    if (this->socket2 != NULL)
    {
        ui->pushButton_c1->setEnabled(true);//按下关闭视频按钮后让开启视频按钮变黑（true）
        ui->pushButton_c2->setEnabled(false);//按下关闭视频按钮后让关闭按钮变灰（false）
        if(timer->isActive())
            timer->stop();
        this->socket2->close();
        this->socket2 = NULL;
        moude = 0;
        ui->stackedWidget->setCurrentIndex(1);
    }
    else
    {
        ui->stackedWidget->setCurrentIndex(1);
    }
}

//***********************************************************************************************

//打开灯光
void Widget::on_lamp_clicked()
{
    if (ui->lamp->text() == "打开灯光")
    {
        flag = LIGHT;
        msg.op = flag;
        strcpy(msg.data, "open");
        //发送指令
        sendData();
        ui->lamp->setText("关闭灯光");
        ui->label_9->setText("open");
    }
    else if (ui->lamp->text() == "关闭灯光")
    {
        flag = LIGHT;
        msg.op = flag;
        strcpy(msg.data, "close");
        //发送指令
        sendData();
        ui->lamp->setText("auto");
        ui->label_9->setText("close");
    }
    else
    {
        flag = LIGHT;
        msg.op = flag;
        strcpy(msg.data, "auto");
        //发送指令
        sendData();
        ui->lamp->setText("打开灯光");
        ui->label_9->setText("auto");
    }
}

//***********************************************************************************************

//温度刷新
void Widget::on_temperature_clicked()
{
    flag = TEMP;
    msg.op = flag;

    //发送指令
    sendData();
}


//***********************************************************************************************

//***********************************************************************************************

//NOBODY模式
void Widget::on_pushButton_4_clicked()
{
    flag = MOD;
    msg.op = flag;
    strcpy(msg.data, "无人模式");
    if(NULL != this->socket2)
    {
        this->socket2->close();
        this->socket2 = NULL;
        if(timer->isActive())
            timer->stop();

    }
    Widget::sleep(2000);
    //发送指令
    sendData();

    openVideo();
}

//***********************************************************************************************

//SLEEP模式
void Widget::on_pushButton_5_clicked()
{
    flag = MOD;
    msg.op = flag;
    strcpy(msg.data, "睡眠模式");

    //发送指令
    if(NULL != this->socket2)
    {
        this->socket2->close();
        this->socket2 = NULL;
        if(timer->isActive())
            timer->stop();

    }
    Widget::sleep(2000);
    sendData();

    openVideo();
}

//***********************************************************************************************

//NORMAL模式
void Widget::on_pushButton_6_clicked()
{
    flag = MOD;
    msg.op = flag;
    strcpy(msg.data, "正常模式");
    if(NULL != this->socket2)
    {
        this->socket2->close();
        this->socket2 = NULL;
        if(timer->isActive())
            timer->stop();

    }
    Widget::sleep(1000);
    //发送指令
    sendData();


}

void Widget::on_screenShot_clicked()
{
       QDateTime  nowTime;//获取实时时间
       QString  timeStr;//保存图片的文件名
       nowTime = QDateTime::currentDateTime();
       timeStr = FILEPATH + nowTime.toString("yyyy-MM-dd hh时mm分ss秒") + ".jpg";
       pixmap->save(timeStr,nullptr,100);
}
void Widget::sleep(unsigned int msec)
{
    QTime dieTime = QTime::currentTime().addMSecs(msec);
    while( QTime::currentTime() < dieTime )
    QCoreApplication::processEvents(QEventLoop::AllEvents, 100);
}
